package com.qjl.parser.logicflow;

import com.qjl.core.ELNode;
import com.qjl.core.ExpressLanguageParseException;
import com.qjl.parser.ELParser;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TransferParser implements ELParser {

	/**
	 * 待转化的数据
	 */
	private TransferNode transferNode;


	/**
	 * init el节点
	 *
	 * @param lfNode Lf节点
	 * @return {@link ELNode}
	 */
	private ELNode initElNode(LfNode lfNode) {
		if (lfNode == null) {
			return null;
		}
		String nodeId = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeId.name());
		String nodeTag = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeTag.name());
		String nodeData = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeData.name());
		String nodeType = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeType.name());
		String conditionNodeId = lfNode.getLfNodeProperty(LfNodePropertyEnum.conditionNodeId.name());

		ELNode node = new ELNode();
		node.setNodeId(nodeId);
		node.setTag(nodeTag);
		node.setData(nodeData);
		node.setName(nodeType);
		node.setConditionNodeId(conditionNodeId);
		if (ELNode.ELNameEnum.COMMON.name().equals(nodeType)) {
			node.setType(ELNode.ELTypeEnum.idType.name());
		} else {
			node.setType(ELNode.ELTypeEnum.elType.name());
		}
		return node;
	}

	@Override
	public ELNode extractElNode() {
		LfNode currentLfNode = transferNode.getLfNode();
		String currentNodeType = currentLfNode.getLfNodeProperty(LfNodePropertyEnum.nodeType.name());

		if (!ELNode.ELNameEnum.COMMON.name().equals(currentNodeType)) {
			throw new ExpressLanguageParseException("第一个节点必须是普通组件");
		}
		ELNode elNode = initElNode(currentLfNode);
		ELNode thenNode = ELNode.initThenNode();
		thenNode.addChild(elNode);
		thenNode.addAllChild(this.doExtract(transferNode));

		return thenNode;
	}

	private List<ELNode> doExtract(TransferNode transferNode) {
		TransferNode currentTransferNode = transferNode;

		List<TransferNode> next = currentTransferNode.getNext();

		List<ELNode> listNodes = new ArrayList<>();
		LfNode currentLfNode = currentTransferNode.getLfNode();
		String currentNodeType = currentLfNode.getLfNodeProperty(LfNodePropertyEnum.nodeType.name());

		if (ELNode.ELNameEnum.WHEN.name().equals(currentNodeType)) {
			List<TransferNode> children2 = currentTransferNode.getChildren();
			ELNode whenElNode = initElNode(currentLfNode);
			listNodes.add(whenElNode);
			buildChild(whenElNode, children2);
		}

		//这种节点可能是IF/ SWITCH
		if (ELNode.ELNameEnum.ifOrSwitch(currentNodeType)) {
			List<TransferNode> next1 = currentTransferNode.getNext();

			ELNode ifOrSwitchElNode = initElNode(currentLfNode);
			listNodes.add(ifOrSwitchElNode);
			buildChild(ifOrSwitchElNode, next1);
			return listNodes;
		}

		if (CollectionUtils.isEmpty(next)) {
			return Collections.emptyList();
		}

		//连续处理只有一个子节点的节点
		while (next.size() == 1) {
			currentTransferNode = next.get(0);
			currentLfNode = currentTransferNode.getLfNode();
			currentNodeType = currentLfNode.getLfNodeProperty(LfNodePropertyEnum.nodeType.name());

			if (ELNode.ELNameEnum.ifOrSwitch(currentNodeType)) {
				//如果是if 或 switch 不继续处理
				break;
			}
			if (ELNode.ELNameEnum.WHEN.name().equals(currentNodeType)) {
				List<TransferNode> children = currentTransferNode.getChildren();
				ELNode whenElNode = initElNode(currentLfNode);
				listNodes.add(whenElNode);

				buildChild(whenElNode, children);
			}

			if (ELNode.ELNameEnum.COMMON.name().equals(currentNodeType)) {
				ELNode elNode = initElNode(currentLfNode);
				listNodes.add(elNode);
			}
			next = currentTransferNode.getNext();

		}

		if (CollectionUtils.isEmpty(next)) {
			return listNodes;
		}
		//这种节点可能是IF/ SWITCH
		if (ELNode.ELNameEnum.ifOrSwitch(currentNodeType)) {
			next = currentTransferNode.getNext();

			ELNode ifOrSwitchElNode = initElNode(currentLfNode);
			listNodes.add(ifOrSwitchElNode);
			buildChild(ifOrSwitchElNode, next);
			return listNodes;
		}


		return listNodes;

	}


	/**
	 * 处理多个节点
	 *
	 * @param fatherElNode
	 * @param children
	 */
	private void buildChild(ELNode fatherElNode, List<TransferNode> children) {
		for (TransferNode c : children) {
			LfNode lfNode = c.getLfNode();
			String currentNodeType = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeType.name());
			String nodeAliasId = lfNode.getLfNodeProperty(LfNodePropertyEnum.nodeAliasId.name());
			ELNode thenNode = ELNode.initThenNode();
			fatherElNode.addChild(thenNode);
			thenNode.setAliasNodeId(nodeAliasId);

			if(ELNode.ELNameEnum.COMMON.name().equals(currentNodeType)){
				ELNode elNode = initElNode(lfNode);
				thenNode.addChild(elNode);
			}
			thenNode.addAllChild(doExtract(c));
		}
	}
}
